﻿/*************************** Ccay IGrid Extend ***********************************/
(function(IGrid) {
	var pagerMsg = IGrid.Const.I18n.pager = {
		pagerSave : "ccay.common.message.confpagersave",
		noResult : 'ccay.common.label.noresult',
		validLose : 'ccay.common.igrid.pagervalidlose'
	};
	// 行转动
	var rowTurn = IGrid.RowTurn = {
		/** @description 普通的行转动拖拽
		 *  @param {Object} e 事件对象
		 *  @param {Object} pos 定位参数
		 *  @param {Object} mover 拖拽面板对象
		 *  @param {Object} trigger 拖拽对象
		 *  @param {Object} dropOp 拖拽配置
		 *  @param {Object} grid IGrid对象
		 */
		commonRowTurn: function (e, pos, mover, trigger, dropOp, grid) {
			var storage = grid.op.Storage;
			if (dropOp.actives) {
				// 获取目标对象
				var target = dropOp.actives.item, 
					dataset = storage.dataset, 
					// 获取当前拖拽对象数据
					currentData = grid.getRowData(trigger),
					// 获取当前拖拽对象数据索引
					currentIdx = currentData._index,
					targetData, targetIdx, tempInsertData;
				if (target) {
					// 将当前拖动对象插入目标对象前
					target.before(trigger);
					// 获取目标对象数据
					targetData = grid.getRowData(target);
					if(currentData._newIndex){
						currentData._index = targetData._index;
					}else{
						// 获取目标对象数据索引
						targetIdx = targetData._index;
						// 移除当前拖拽对象数据
						dataset.splice(currentIdx, 1);
						// 若当前数据在目标数据前，则需目标对象索引 - 1，否则索引不变
						if (currentIdx < targetIdx) {
							targetIdx = targetIdx - 1;
						}
						// 在数据集中将目标对象数据前添加该拖拽数据
						dataset.splice(targetIdx, 0, currentData);
					}
				} else {
					// 将当前拖动对象插入最后
					dropOp.actives.panel.append(trigger);
					// 移除当前拖拽对象数据
					dataset.splice(currentIdx, 1);
					// 在数据集中将当前对象加进去
					dataset.push(currentData);
				}
				// 重新加载grid
				grid.reload();
			}
		}
	};
	
	var Extend = {
		/** @description 设置列的渲染器配置
		 *  @param {Object} grid IGrid对象
		 *  @param {Object} col 列的配置信息
		 *  @param {Object} op grid的配置信息
		 */
		setCol : function(grid, col, op) {
			// 注册IGrid列头国际化功能
			col.header = col.header ? $i18n(col.header).encode() : (col.name ? $i18n(col.name).encode() : "");
			// 注册IGrid渲染器render功能 
			if (!col.inner && !col.columnType) {
				// 标示列的渲染方式
				if (col.content && !col.renderer) {
					col._contentTd = true;
				} else {
					var renderer = col.renderer;
					if (renderer) {
						if (typeof(renderer) == "string") {
							col.renderer = Ccay.UI.Renderer.get(renderer);
						} else if (typeof(renderer) != "object" || renderer.__type != "iobject"){
							op._renderRow = true;
							col._renderTd = true;
						}
					} else {
						col.renderer = Ccay.UI.Renderer.get(col.type);
					}
					// 给format设置默认值
					col.format || (col.format = {});
					// 设置渲染器的参数
					col.renderer.setOption && col.renderer.setOption(col);
				}
				// 判断当前列是时间格式将进行转换
                if (col.type == "date" || col.type == "datetime") {
                	var type = col.format && (col.format.dateFormat || col.format.renderFormat) || Ccay.Config.Format[col.type];
                	op._dateFields.push({"field": col.field, "type": type});
                }
                // 判断当前列是否存在映射字段
                if (col.mappingRenderField) {
                	var funcParam, func, index = 2, content = col.content;
                	// 若存在映射方法，则优先使用，否则将content转换成方法
					if (col.mappingFunc) {
						funcParam = col.field;
						func = col.mappingFunc;
					} else {
						(content.charAt(2) == "#") && index++;
						funcParam = content.substring(content.indexOf("(") + 1, content.indexOf(",") > 0 ? content.indexOf(",") : content.indexOf(")"));
						func = Ccay.DataHelper.getObj(content.substring(index, content.indexOf("(")));
					}
					op._mappingFields.push({"field": col.mappingRenderField, "funcParam": funcParam, "func" : func});
					hasMappingFields = true;
                }
			}
			// 注册IGrid列权限显示功能
			if (col.permission && !Ccay.Permission.check(col.permission)) {
				// 标示列没有权限
				col._noPermission = true;
				// 将列进行隐藏
				col.hidden = true;
			}
			// 注册IGrid列权限编辑功能
			if (col.editPermission && !Ccay.Permission.check(col.editPermission)) {
				col.editable = false;
			}
			// 不折行默认显示Tip
			if (!op.wrap && col.type == "longtext" && col.showTip !== false) {
				col.showTip = true;
			}
			// 添加Tip样式，标示该列进行Tip提示
			if (col.showTip) {
				col.cssName += " grid-tip";
				op.showTip = true;
			}
			// 判断标题是否显示Tip
			if (op.headTip && !col.inner) {
				col._headCss += " grid-tip";
				op.showTip = true;
			}
		},
		/** @description 判断IGrid是否有编辑权限
		 *  @param {Object} grid IGrid对象
		 *  @param {Object} op grid的配置信息
		 */
		checkEditor : function(grid, op) {
			if (op.editPermission && !Ccay.Permission.check(op.editPermission)) {
				op.editMode = false;
			}
		},
		/** @description 列设置应用modal数据
		 *  @param {Object} grid IGrid对象
		 *  @param {Object} op grid的配置信息
		 */
		checkColumns: function (grid, op) {
			var cols = op.columns;
			if (cols && cols.length) {
				var curColumns = [],modal;
				$.each(cols,function(i,col){
					modal = col && col.modal;
					if(modal && Ccay.Modal.isModal(modal))
					{
						//将modal的field转换成column
						modal.each(function(field){
							if(field.colOp !== false)
								curColumns.push(Extend.filedToColumn({field:field}));
						});
					}
					else
						col && curColumns.push(Extend.filedToColumn(col));
				});
				op.columns = curColumns;
			}
		},
		/** @description 将col设置的filed转换成igrid的列设置
		 *  @param {Object} col 列设置
		 */
		filedToColumn:function(col){
			var filed = col.field;
			if($.isPlainObject(filed))
			{
				var setting = $.extend(true, {}, filed,filed.colOp ? $.extend(true,{},filed.colOp,col.colOp) : col.colOp);
				setting.colOp && delete setting.colOp;
				return setting;
			}
			return col;
		},
		/** @description 设置Tip显示
		 *  @param {Object} grid IGrid对象
		 *  @param {Object} op grid的配置信息
		 */
		setTip : function(grid, op) {
			if (op.showTip) {
				grid.dom.tip({
							global:true,
							child : '.grid-tip',
							tipProp : "tip",
							addTipStyle : false,
							offset:true,
							showOverflow:op.showOverflow,
							width: op.tipWidth || 200
						});
			}
		},
		/** @description 执行初始化完成事件
		 *  @param {Object} grid IGrid对象
		 *  @param {Object} op grid的配置信息
		 */
		initComplete: function (grid, op) {
			Extend.setTip(grid, op);
			Extend.renderRow(grid, op);
		},
		/** @description 渲染行
		 *  @param {Object} grid IGrid对象
		 *  @param {Object} op grid的配置信息
		 */
		renderRow: function (grid, op) {
			// 若grid的列设置中的渲染是方法时，则执行行渲染功能
			if (op._renderRow) {
				delete op._renderRow;
				var fnRenderRow = op.fnRenderRow;
				op.fnRenderRow = function (row, data, i) {
					// 渲染行对象
					Extend.renderRowDom(row, data, i, this);
					fnRenderRow && fnRenderRow.call(this, row, data, i);
				}
			}
		}, 
		/** @description 渲染行对象
		 *  @param {Object} grid IGrid对象
		 *  @param {Object} op grid的配置信息
		 */
        renderRowDom : function (row, data, rowNo, grid) {
        	// 遍历行的列对象
        	row.find('.grid-cell').each(function (i) {
        		var td = $(this), col = grid.getColumnOp(td), value;
        		// 列渲染存在并且是方法时，则执行该方法，进行单元格的渲染
        		if (col._renderTd) {
        			value = Ccay.DataHelper.getObj(col.field, data);
        			td.html(typeof col.renderer == "function" ? col.renderer(value, data, col, grid, col._i, rowNo):value);
        		}
        	});
        },
		/** @description 窗口大小改变是触发的事件
		 *  @param {Object} event 参数设置
		 */
		changeResize : function(event) {
			var grid = event.data, gridMag = grid.gridMag, gridOp = gridMag.op, scrollOp = gridOp._scrollOp,
				// 获取浏览器的高度
				fullBodyHeight = grid.fullContainer.height() - grid.fixeHeight - 30,
				// 获取数据面板的最小高度
				bodyPanelHeight = grid.bodyPanel.css("min-height");
			// 若最小高度不是数字，则设置默认值
			if (!$.isNumeric(parseInt(bodyPanelHeight))) {
				bodyPanelHeight = grid.bodyPanel.height() || 24;
			}
			// 如果窗口高度小于grid的最小高度时，窗口显示竖向滚动条，否则，去掉竖向滚动条
			if (fullBodyHeight < parseInt(bodyPanelHeight) + 70) {
				grid.fullContainer.css("overflow-y", "auto");
			} else {
				grid.fullContainer.css("overflow-y", "");
			}
			// 设置数据区域的样式
			grid.bodyPanel.removeAttr("style").css({
				"height" : "",
				"min-height" : gridOp.height || gridOp.minHeight || null,
				"max-height" : fullBodyHeight
			});
			// 滚动加载执行
			if (gridOp.lazyLoad == true && scrollOp) {
				// 全屏时的总条数
				var totalSize = Math.ceil(fullBodyHeight / gridOp.rowHeight);
				// 通过全屏高度设置每次滚动加载的条数
				scrollOp.pageSize = parseInt(gridMag.setScrollSize(fullBodyHeight));
				// 判断是否是最后一页，若是则改变开始显示数据；若不是则修改结束显示数据
				if (scrollOp.end < scrollOp.total) {
					scrollOp.end = scrollOp.showStart + scrollOp.pageSize;
					scrollOp.showEnd = scrollOp.showStart + totalSize;
				} else {
					var tempStart = scrollOp.showEnd - scrollOp.pageSize,
						tempShowStatr = scrollOp.total - totalSize;
					scrollOp.start = (tempStart < 0) ? 0 : tempStart;
					scrollOp.showStart = (tempShowStatr < 0) ? 0 : tempShowStatr;
				}
				// 重新加载数据
				gridOp.scrollLoader.load();
			}
		},
		/** @description 最大化状态的点击事件
		 *  @param {Object} target 当前点击对象
		 *  @param {Object} grid IGrid对象
		 *  @param {Object} op grid的配置信息
		 */
		maximizeClick : function (target, grid, op) {
			target.hide().next().show();
			$(op.fullPanel).fullScreen();
			!op.toolPanel && grid.hideToolBar();
			$("#ccay_fullscreen_overlay").show();
		},
		/** @description 正常状态的点击事件
		 *  @param {Object} target 当前点击对象
		 *  @param {Object} grid IGrid对象
		 *  @param {Object} op grid的配置信息
		 */
		normalClick : function (target, grid, op) {
			target.hide().prev().show();
			$(op.fullPanel).fullScreen();
			!op.toolPanel && grid.hideToolBar();
			$("#ccay_fullscreen_overlay").hide();
		},
		changeSearchMode : function (target, type, grid, op) {
			var searchPanel = op.operation.search.panel,
				customSetting = $.extend({}, Ccay.Personalized.getCurrPageSettings(grid.id) || {});
			if (type == "search") {
				target.hide().next().show();
				// 清空正在使用的过滤条件
				op._filters && (op._filters = {}); 
				op._inputFilters && (op._inputFilters = {});
	    		op._cusFilters && (op._cusFilters = {});
	    		op.pagerOp.pageInf.filter && (op.pagerOp.pageInf.filter = "[]".encodeURI());
			} else {
				target.hide().prev().show();
				// 清空正在使用的搜索条件
				op.ajax.data && (op.ajax.data = {});
			}
			customSetting.switchMode = type;
			// 保存
			op.customSetting && Ccay.Personalized.saveSetting(grid.id, {switchMode : type});
			grid.clearCache();
			grid.reInit(customSetting);
			
		},
		switchClick : function (target, type, grid, op) {
			if (!op._cache && grid.getRecords()) {
				Ccay.UI.confirm(pagerMsg.pagerSave, function(result) {
					if (result) {
						var saveBtn = op.operation && op.operation.save && op.operation.save.btn;
						if(grid.valid() && saveBtn) {
							$(saveBtn).click();
							Extend.changeSearchMode(target, type, grid, op);
						} else {
							Ccay.UI.showMessage(pagerMsg.validLose, "warn");
						}
					}
					else{
						Extend.changeSearchMode(target, type, grid, op);
					}
				}, true);
			} else {
				Extend.changeSearchMode(target, type, grid, op);
			}
			
		},
		/** @description 给更新数据添加监听方法
		 *  @param {Object} grid IGrid对象
		 *  @param {Object} op grid的配置信息
		 */
		extendStorage: function (grid, op) {
			var storage = op.Storage;
			// 将更新的列标示缓存起来
			storage.Trigger.update.add(function (item, change, args) {
				var updFields = item._updFields;
				if (updFields) {
					!updFields.contains(args) && item._updFields.push(args);
				} else {
					item._updFields = [args];
				}
			});
		},
		/** @description grid的行拖拽
		 *  @param {Object} grid IGrid对象
		 *  @param {Object} op grid的配置信息
		 */
		gridRowDrop: function (grid, op) {
			var gridDom = grid.dom,
				bodyPanel = grid.getDataBody(),
				fnRowDrag = op.fnRowDrag,
				fnRowMove = op.fnRowMove,
				fnBeginRowDrop = op.fnBeginRowDrop,
				fnEndRowDrop = op.fnEndRowDrop;
			gridDom.addClass("ccay-igrid-rowdrop");
			gridDom.drop({
				target: '.grid-row',
				clickable: true,
				signMode : "ver",
				panels: bodyPanel,
				offset: true,
				onDragStart: function(e, pos, mover, trigger, op) {
					if(!fnRowDrag || fnRowDrag.call(grid, e, pos, mover, trigger, op) !== false) {
						mover.width(gridDom.width()).text(trigger.children("td:eq(2)").text());
					} else {
						return false;
					}
				},
				onMoving: function (e, pos, mover, trigger, op) {
					if(fnRowMove && fnRowMove.call(grid, e, pos, mover, trigger, op) === false) {
						return false;
					}
				},
				onDroped: function(e, pos, mover, trigger, op){
					if(!fnBeginRowDrop || fnBeginRowDrop.call(grid, e, pos, mover, trigger, op) !== false) {
						rowTurn.commonRowTurn(e, pos, mover, trigger, op, grid);
						fnEndRowDrop && fnEndRowDrop.call(grid, e, pos, mover, trigger, op);
					}
				}
			});
		}
	};

	/** 注册扩展插件 */
	Ccay.UI.XControl.addPlugin("XGrid", "extend", {
				preInit : function(grid, op) {
					// 判断IGrid是否有编辑权限
					Extend.checkEditor(grid, op);
					// 列设置应用modal数据
					Extend.checkColumns(grid, op);
					// 初始化列设置
					op.handler.setColumn.add(Extend.setCol);
					// 初始化Tip设置
					op.handler.initComplete.add(Extend.initComplete);
				},
				build : function (grid, op) {
					// 扩展Storage
					!op._reIniting && Extend.extendStorage(grid, op);
					// 数据行拖拽功能
					op.allowRowDrop && op.handler.complete.add(Extend.gridRowDrop);
				},
				miniToolBar: function (grid, op, toolBarButton) {
					// 搜索过滤切换
					if (op.showSwitch && op.allowFilter && ((op.operation && op.operation.search && op.operation.search.panel) || op.genSearchByFilter)){
						var inquireIcon = "inquire",
							screeningIcon = "screening hide";
						// 若是筛选模式，则显示筛选图标，否则显示查询图标
						if (op.switchMode == "search") {
							inquireIcon = "inquire hide";
							screeningIcon = "screening";
						} else {
							// 设置过滤模式下的高度
							if (op.heightOfFilterMode) {
								grid.getBodyPanel().height(op.heightOfFilterMode);
								// 修正滚动条
								IGrid.Factory.fixScroll(grid, op);
							}
						}
						toolBarButton.push({
							type: "img",
							icon: inquireIcon,
							text: "ccay.common.igrid.switchSearchMode",
							click: function () {
								Extend.switchClick($(this), "search", grid, op);
							}
						}, {
							type: "img",
							icon: screeningIcon,
							text: "ccay.common.igrid.switchFilterMode",
							click: function () {
								Extend.switchClick($(this), "filter", grid, op);
							}
						});
					}
					// 全屏设置
					if (op.fullPanel) {
						// 初始化全屏设置
						if(!op._reIniting){
							Ccay.UI.FullScreen.init(grid);
						}
						var maximizeIcon = "panel-maximize",
							normalIcon = "panel-normal hide";
						// 若是全屏状态，则显示最小化图标，否则显示最大化图标
						if ($(op.fullPanel).hasClass("ccay-fullscreen-full")) {
							maximizeIcon = "panel-maximize hide";
							normalIcon = "panel-normal";
						}
						// 添加工具栏按钮
						toolBarButton.push({
							type: "img",
							icon: maximizeIcon,
							text: "ccay.common.widget.maximize",
							click: function () {
								Extend.maximizeClick($(this), grid, op);
							}
						}, {
							type: "img",
							icon: normalIcon,
							text: "ccay.common.widget.normal",
							click: function () {
								Extend.normalClick($(this), grid, op);
							}
						});
					}
				},
				clear: function (grid, gridOp, oldOp) {
					if (gridOp.fullPanel && $(gridOp.fullPanel).hasClass("ccay-fullscreen-full")) {
						gridOp._fullOp = oldOp._fullOp;
						gridOp.height = null;
						gridOp.maxHeight = oldOp._fullOp.maxHeight;
						gridOp.minHeight = oldOp._fullOp.minHeight;
					}
				}
			});

	/** 注册扩展全屏实现 */
	Ccay.UI.XControl.extendIManager("XGrid", {
				/** @description 全屏实现
				 *  @param {Object} container 全屏容器
				 *  @param {Number} fullHeight 全屏高度
				 *  @param {Boolean} isFull 是否是全屏设置
				 */
				fullScreen : function(container, fullHeight, isFull) {
					var grid = this, bodyPanel = grid.getBodyPanel(), gridOp = grid.op, winPanel = $(window), 
						siblingsAllHeight = function (){
							var siblingsHeight = 0;
							grid.dom.siblings().each(function(){
								siblingsHeight += $(this).outerHeight();
							});
							return siblingsHeight;
						};
					// 全屏时执行
					if (isFull) {
						// 缓存原始设置
						gridOp._fullOp || (gridOp._fullOp = {
							// 缓存普屏时滚动加载时页面显示数据条数
							scrollOp: gridOp._scrollOp,
							// 除了数据面板外，其他元素的固定高度
							fixedHeight: siblingsAllHeight() + grid.getHeadPanel().outerHeight() + grid.getBottom().outerHeight(),
							oriHeight: gridOp.height,
							oriMinHeight: gridOp.minHeight,
							oriMaxHeight: gridOp.maxHeight,
							minHeight: gridOp.height || gridOp.minHeight || null
						});
						var fullBodyHeight, scrollOp = gridOp._fullOp.scrollOp, event = {
							"gridMag": grid,
							"bodyPanel": bodyPanel,
							"fixeHeight": gridOp._fullOp.fixedHeight,
							"fullContainer" : container
						};
						// 浏览器窗口绑定改变大小事件
						winPanel.bind("resize", event, Extend.changeResize);
						// 全屏时，修复滚动条滚动的隐藏列
						IGrid.Factory.fixScrollToFullScreen(this);
						// 执行浏览器窗口改变事件
						Extend.changeResize({data : event});
						// 缓存最大高度设置
						gridOp._fullOp.maxHeight = parseInt(bodyPanel.css("max-height"));
					// 普屏时执行
					} else {
						// 移除浏览器窗口绑定改变大小事件
						winPanel.unbind("resize", Extend.changeResize);
						// 恢复数据区域的样式
						bodyPanel.removeAttr("style").css({
							"height" : gridOp._fullOp.oriHeight || null,
							"min-height" : gridOp._fullOp.oriMinHeight || null,
							"max-height" : gridOp._fullOp.oriMaxHeight || null
						});
						// 恢复普屏滚动加载执行
						if (gridOp.lazyLoad == true && gridOp._scrollOp) {
							gridOp._scrollOp = gridOp._fullOp.scrollOp;
							gridOp.scrollLoader.load();
						}
					}
					Ccay.UI.IGrid.Factory.fixScroll(grid,gridOp);
				},
				renderValue: function (td, col, value, isRenderTd, rowData) {
					var renderer = col.renderer,
						dataHelper = Ccay.DataHelper;
			    	// value为空获取单元格数据，不为空为赋值
			    	if (value == null) {
				    	rowData || (rowData = this.getRowData(td));
					    var tempField = dataHelper.getObj(col.field, rowData), tempValue;
					    tempField = (tempField == null) ? "" : tempField;
					    if (col.valueField) {
					    	if (col._renderTd || col._contentTd) {
					    		tempValue = dataHelper.getObj(col.valueField, rowData);
					    		tempValue = (tempValue == null) ? "" : tempValue;
					    		return {
					    			value: tempValue,
					    			text: tempField
					    		};
					    	} else {
					    		var tempValue = renderer.getValue(td, col.format);
					    		// 将单元格中的全角空格， 转换成半角空格
					    		//tempValue.text.replace(/\s/g, " ");
					    		return tempValue;
					    	}
					    }
					    return tempField;
			    	} else {
			    		if (!isRenderTd) {
			    			//修复currency类型使用content渲染出现的问题。
			    			var colRule = Ccay.UI.Config.Editor.rules[col.type],colRender=Ccay.UI.Renderer.get(col.type);
			    			if(colRule  && colRender && (colRule.number || colRule.digits)){
			    				return colRender.parse(value,col.format);
			    			}
			    			// 若不是渲染组件，则不需要转换数据类型
		    				return (col._renderTd || col._contentTd) ? value : renderer.parse(value, col.format);
			    		} else {
				    		// 重写渲染，若不是渲染组件，则调用用户自定义的渲染方法
    						if (col._renderTd || col._contentTd) {
    							var tempContent = col._renderTd ? 
			        					renderer(value, rowData, col, this, col._i, this.getRowNo(td)) :
    									Ccay.UI.template("<% with(data){ %>"+ col.content + " <% } %>",{data:rowData}, null, null, {_grid: this});
			        			td.html(tempContent);
				    		} else {
				    			renderer.render(td, value, col.format);
				    		}
			    		}
					}
			    }
			});
})(Ccay.UI.IGrid);